﻿using Chaotic.Core.Extension;
using Chaotic.DataBase.DBAccessLibrary.DBAccessLibrary;
using Chaotic.DataBase.DBAccessLibrary.Interface;
using Chaotic.DataBase.DBAccessLibrary.Model;
using Chaotic.Module.DBTool.Common;
using Chaotic.Module.DBTool.Models;
using MediaFoundation;
using Microsoft.SqlServer.TransactSql.ScriptDom;
using SharpDX.Direct3D9;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.FieldList;
using Telerik.Windows.Controls.SyntaxEditor.Tagging.Taggers;
using Telerik.Windows.Controls.SyntaxEditor.UI;
using Telerik.Windows.Controls.SyntaxEditor.UI.IntelliPrompt.Completion;
using Telerik.Windows.Documents.Spreadsheet.Expressions.Functions;
using Telerik.Windows.Persistence.Core;
using Telerik.Windows.SyntaxEditor.Core.Tagging;
using Telerik.Windows.SyntaxEditor.Core.Text;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Chaotic.Module.DBTool.ViewModels
{
    public class SqlContentViewModel : BindableBase
    { 
        RadSyntaxEditor _sqlEditor;
        private readonly IDBRabbionCommandMenu _dBRabbionCommandMenu;
        CustomSqlTagger _customSqlTagger;
        SqlCompletionListPopup _sqlCompletionListPopup;
        private string _originalText;
        public SqlContentViewModel(IEventAggregator eventAggregator, IDBRabbionCommandMenu dBRabbionCommandMenu)
        {
            _dBRabbionCommandMenu = dBRabbionCommandMenu;

            TabTextCommand = new Prism.Commands.DelegateCommand(() => {
                if (string.IsNullOrEmpty(_lastKeyWord))
                    return;

                string? cmd = DBOperatorFactory.GetGrammar(SysCache.DBConnection)?.AppendTabText(_lastKeyWord);
                if(!string.IsNullOrEmpty(cmd))
                {
                    Span replaceSpan = new Span(SqlEditor.CaretPosition.Index - 1, 1);
                    this.SqlEditor.Document.Replace(replaceSpan, cmd);
                }
            });
            eventAggregator.ResgiterMessage<DBToolMessage>(message =>
            {
                if(message is { Target: nameof(SqlContentViewModel), ActionName: "ConnectToDb" })
                {
                    LoadTableKeyWorks();
                }
            }); 
        }
        public RadSyntaxEditor SqlEditor
        {
            get => _sqlEditor;
            set
            {
                if (_sqlEditor != value)
                {
                    _sqlEditor = value;
                    _sqlEditor.Loaded += _sqlEditor_Loaded;
                    LoadSqlDocument();
                }
            }
        }

        SqlContentMessage _msg;
        public void InsertSql(SqlContentMessage msg)
        {
            if(this.SqlEditor == null)
            {
                _msg = msg;
                return;
            }
            this.SqlEditor.Insert(msg.Sql);
            if ((msg.Status & SqlControlStatus.NewLine) == SqlControlStatus.NewLine)
            {
                this.SqlEditor.Insert(Environment.NewLine);
            }
            if ((msg.Status & SqlControlStatus.Run) == SqlControlStatus.Run)
            {
                SelectedText = msg.Sql; 
            }
        }

        Prism.Commands.DelegateCommand TabTextCommand { get; set; }
        private void _sqlEditor_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            _sqlEditor.KeyBindings.RegisterCommand(_dBRabbionCommandMenu.SqlIncreaseCommand, System.Windows.Input.Key.K, System.Windows.Input.ModifierKeys.Control);
            _sqlEditor.KeyBindings.RegisterCommand(_dBRabbionCommandMenu.SqlDecreaseCommand, System.Windows.Input.Key.U, System.Windows.Input.ModifierKeys.Control);
            _sqlEditor.KeyBindings.RegisterCommand(_dBRabbionCommandMenu.FileSaveCommand, System.Windows.Input.Key.S, System.Windows.Input.ModifierKeys.Control);
            _sqlEditor.KeyBindings.RegisterCommand(_dBRabbionCommandMenu.SqlRunCommand, System.Windows.Input.Key.F5);
            //_sqlEditor.KeyBindings.RegisterCommand(TabTextCommand, System.Windows.Input.Key.Tab);

            if(_msg != null)
            {
                InsertSql(_msg);
                _msg = null;
            }
        }

        string _selectedText = string.Empty;
        public string SelectedText
        {
            get => _selectedText;
            set
            {
                if (_selectedText != value)
                {
                    this.SetProperty(ref _selectedText, value);
                    _dBRabbionCommandMenu.RaiseCanExecuteChangedBySelectText();
                }
            }
        }

        string _documentHeaderTitle = string.Empty;
        /// <summary>
        /// 标题栏标题
        /// </summary>
        public string DocumentHeaderTitle
        {
            get => _documentHeaderTitle;
            set
            {
                if (_documentHeaderTitle != value)
                {
                    this.SetProperty(ref _documentHeaderTitle, value); 
                }
            }
        }

        bool _isChangeDocument;
        /// <summary>
        /// 是否有修改
        /// </summary>
        public bool IsChangeDocument
        {
            get => _isChangeDocument;
            set
            {
                if (_isChangeDocument != value)
                {
                    this.SetProperty(ref _isChangeDocument, value);
                }
            }
        }

        public string FilePath { get; set; }
        public bool IsNewDocument { get; set; }
        

        List<CompletionInfo> _completionList = new();

        private readonly List<CompletionInfo> _defaultCompletionList = new();
        private readonly List<CompletionInfo> _tableCompletionList = new();
        private readonly List<CompletionInfo> _procCompletionList = new();
        private readonly List<CompletionInfo> _columnCompletionList = new();

        private void LoadSqlDocument()
        {
            if (IsNewDocument)
            {
                _sqlEditor.Document = new TextDocument();
            }
            else
            {
                Stream stream = !File.Exists(FilePath) ?
                    File.Create(FilePath) :
                    File.OpenRead(FilePath);
                using (stream)
                {
                    StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                    _sqlEditor.Document = new TextDocument(reader);
                }
            }
            _originalText = _sqlEditor.Document.CurrentSnapshot.GetText();
            _sqlEditor.Document.TextContentChanging += Document_TextContentChanging;
            _sqlEditor.Document.TextContentChanged += Document_TextContentChanged;
            _sqlEditor.Selection.SelectionChanged += _sqlEditor_SelectionChanged;

            ////隐藏换行符号
            //FrameworkElement frameworkElement = this.editor.Margins.ScrollableRight.FirstOrDefault(x => x is IndicatorsMargin<System.Windows.Shapes.Path>);
            //if (frameworkElement != null)
            //    frameworkElement.Visibility = Visibility.Collapsed;

            //注册折叠标记器
            _sqlEditor.TaggersRegistry.RegisterTagger(new SqlFoldingTagger(_sqlEditor));
            //注册关键字标记器
            ISqlKeyword sqlKeyword = DBOperatorFactory.GetSqlKeywords(SysCache.DBConnection);
            _customSqlTagger = new CustomSqlTagger(_sqlEditor, sqlKeyword);
            _customSqlTagger.Init();
            _sqlCompletionListPopup = new SqlCompletionListPopup(_sqlEditor);
            _sqlCompletionListPopup.TextInserting += CompletionListWindow_TextInserting;
            ResetCompletion(); 
        }

        private void ResetCompletion()
        {
            ImageSource keyWordImageSource = ImageSourceExtension.GetImageSource("Chaotic.Module.DBTool", "Images/Tree/string-16x16.png");

            _defaultCompletionList.Clear();
            foreach (string item in _customSqlTagger.SqlKeywords.Keywords)
                _defaultCompletionList.Add(new CompletionInfo(item.ToLower(), keyWordImageSource));

            ImageSource functionImageSource = ImageSourceExtension.GetImageSource("Chaotic.Module.DBTool", "Images/Tree/function-16x16.png");
            foreach (string item in _customSqlTagger.SqlKeywords.Functions)
                _defaultCompletionList.Add(new CompletionInfo(item.ToLower(), functionImageSource));

            ImageSource dataTypeImageSource = ImageSourceExtension.GetImageSource("Chaotic.Module.DBTool", "Images/Tree/data-type16x16.png");
            foreach (string item in _customSqlTagger.SqlKeywords.DataTypes)
                _defaultCompletionList.Add(new CompletionInfo(item.ToLower(), dataTypeImageSource));

            _completionList = _defaultCompletionList;
        }
      
        private void LoadTableKeyWorks()
        {
            _tableCompletionList.Clear();
            if (SysCache.TableList == null)
            {
                return;
            }

            ImageSource tableImageSource = ImageSourceExtension.GetImageSource("Chaotic.Module.DBTool", "Images/Tree/table.png"); 
            foreach (TableEntity table in SysCache.TableList)
            {
                _tableCompletionList.Add(new CompletionInfo(table.Name,table.ChName, tableImageSource));
            }

            if (SysCache.ViewList != null)
            {
                ImageSource viewImageSource = ImageSourceExtension.GetImageSource("Chaotic.Module.DBTool", "Images/Tree/view.png");
                foreach (ViewEntity view in SysCache.ViewList)
                {
                    _tableCompletionList.Add(new CompletionInfo(view.Name, viewImageSource));
                }
            }

            if (SysCache.ProcList != null)
            {
                ImageSource procImageSource = ImageSourceExtension.GetImageSource("Chaotic.Module.DBTool", "Images/Tree/proc.png");
                foreach (ProcEntity proc in SysCache.ProcList)
                {
                    _procCompletionList.Add(new CompletionInfo(proc.Name, procImageSource));
                }
            }
            _customSqlTagger.SqlKeywords = DBOperatorFactory.GetSqlKeywords(SysCache.DBConnection);
            ResetCompletion();

        }
        private void LoadColumnKeyWorks(List<TableReferenceInfo>? dic,string alias)
        {
            if(dic == null || dic.Count == 0 || SysCache.TableList == null)
            {
                _columnCompletionList.Clear();
                return;
            }

            _columnCompletionList.Clear();
            TableReferenceInfo? tableReferenceInfo;
            if (!string.IsNullOrEmpty(alias))
            {
                tableReferenceInfo = dic.FirstOrDefault(o => o.TableName == alias || o.Alias == alias);
            }
            else
            {
                tableReferenceInfo = dic.LastOrDefault();
            }
            if (tableReferenceInfo != null)
            {
                TableEntity? tableEntity = SysCache.TableList.FirstOrDefault(o => o.Name?.ToLower() == tableReferenceInfo.TableName.ToLower());
                if (tableEntity != null)
                {
                    foreach (FieldEntity fieldEntity in tableEntity.FieldNodes)
                    {
                        _columnCompletionList.Add(new CompletionInfo(fieldEntity.ColumnName, fieldEntity.TypeName));
                    }
                }
            }
        }

        private void CompletionListWindow_TextInserting(object? sender, Telerik.Windows.Controls.SyntaxEditor.CompletionListTextInsertingEventArgs e)
        {
            filterText = string.Empty;
            _filterStart = 0;
            _filterEnd = 0;
        }
 

        private void _sqlEditor_SelectionChanged(object? sender, EventArgs e)
        {
            SelectedText = _sqlEditor.Selection.GetSelectedText();
        }

        string filterText;
        int _filterStart;
        int _filterEnd;
        string _lastKeyWord;
        private readonly string[] clearFilter = [",", ";", "'"," ", "\n","\r"];
 
        private void Document_TextContentChanging(object? sender, TextContentChangingEventArgs e)
        { 
            _lastKeyWord = e.Change.NewText;

            if (clearFilter.Contains(e.Change.NewText))
            {
                filterText = string.Empty;
                _filterStart = 0;
                _filterEnd = 0;
            }
            else
            {
                if (e.Change.Delta < 0)
                {
                    int index = e.Change.OldSpan.Start;
                    if (!string.IsNullOrEmpty(filterText) && index > _filterStart && index < _filterEnd)
                    {
                        _filterEnd -= 1;
                        filterText = filterText.Remove(index - _filterStart, 1);
                    }
                    else
                    {
                        filterText = string.Empty;
                        _filterStart = 0;
                        _filterEnd = 0;
                    }
                }
                else
                {
                    if (string.IsNullOrEmpty(filterText))
                    {
                        _filterStart = e.Change.NewSpan.Start;
                    }
                    if (_filterEnd == 0 || _filterEnd == e.Change.NewSpan.Start)
                        filterText += e.Change.NewText;
                    else
                    {
                        int index = e.Change.NewSpan.Start;
                        if (index > _filterStart && index < _filterEnd)
                        {
                            _filterEnd += 1;
                            filterText = filterText.Insert(index - _filterStart, e.Change.NewText);
                        }
                        else
                        {
                            filterText = string.Empty;
                            _filterStart = 0;
                            _filterEnd = 0;
                        }
                    }
                    _filterEnd = e.Change.NewSpan.End;
                } 
            }

            //ChangeCompletionList(e.Change);
        }

        private void Document_TextContentChanged(object? sender, TextContentChangedEventArgs e)
        {
            ChangeCompletionList();
            ChangeTitle();
        }

        private void ChangeCompletionList()
        {
            //string sql = GetFocusSqlContent(change); 
           string sql = GetFocusSqlContent();

            if (string.IsNullOrEmpty(sql))
                return;

            List<TableReferenceInfo> dic = SqlParserManager.Instance.ParseTablesWithAliases(sql, out IList<TSqlParserToken> sqlParserTokens);

            TSqlParserToken? endToken = null;
            if (sqlParserTokens != null)
            { 
                if (sqlParserTokens.Count > 0)
                {
                    endToken = GetEndToken(sqlParserTokens, sqlParserTokens.Count - 1);
                }

                if (SetNextCompletionList(endToken, dic, sqlParserTokens))
                {
                    ShowCompletionListWindow(endToken);
                }
            }
        }

        private string GetFocusSqlContent(TextChange change)
        {
            TextSnapshotLine? textSnapshotLine = _sqlEditor.Document.CurrentSnapshot.Lines.FirstOrDefault(o => o.LineNumber == _sqlEditor.CaretPosition.LineNumber);
            if (textSnapshotLine == null)
                return string.Empty;
            string sql = textSnapshotLine.GetText();
            if (change.Delta < 0)
            {
                //删除
                if (!string.IsNullOrEmpty(sql))
                {
                    int index = change.OldSpan.Start - textSnapshotLine.Span.Start;
                    int length = change.OldSpan.End - change.OldSpan.Start;
                    if (sql.Length >= length && index >= 0 && index < sql.Length)
                        sql = sql.Remove(index, length);
                }
            }
            else
            {
                int index = change.OldSpan.Start - textSnapshotLine.Span.Start;
                if (index >= 0 && index < sql.Length)
                {
                    sql = sql.Remove(index, change.OldSpan.Length);
                    sql = sql.Insert(index, _lastKeyWord);
                }
            }
            return sql;
        }
        private string GetFocusSqlContent()
        {
            int focusLineNumber = _sqlEditor.CaretPosition.LineNumber;
            //获取所有的内容并按 换行符 分割
            var text = _sqlEditor.Document.CurrentSnapshot.GetText();
            var lines = text.Split('\n');
            var regions = new Stack<int>();
            //只要有空行 就代表一个代码块的结束
            for (int i = 0; i < lines.Length; i++)
            {
                var line = lines[i];
                if (string.IsNullOrWhiteSpace(line))
                {
                    if (regions.Count > 0)
                    {
                        var startLine = regions.Pop();

                        //如果开始行和结束行相等 则不处理
                        if (startLine == i - 1)
                        {
                            if(startLine == focusLineNumber)
                                return lines[i-1];
                            continue;
                        }
                        TextSnapshotLine textSnapshotLine = _sqlEditor.Document.CurrentSnapshot.Lines.FirstOrDefault(o => o.LineNumber == startLine);
                        var startOffset = textSnapshotLine.Span.Start;
                        TextSnapshotLine iSnapshotLine = _sqlEditor.Document.CurrentSnapshot.Lines.FirstOrDefault(o => o.LineNumber == i - 1);
                        var endOffset = iSnapshotLine.Span.End;

                        if (startOffset < endOffset)
                        {
                            if(startLine <= focusLineNumber && i - 1 >= focusLineNumber)
                            {
                                var span = new TextSnapshotSpan(_sqlEditor.Document.CurrentSnapshot, new Span(startOffset, endOffset - startOffset));
                                return span.GetText();
                            }
                        }
                    }
                }
                else
                {
                    if (regions.Count == 0)
                        regions.Push(i);
                }
            }

            if (regions.Count > 0)
            {
               var startLine = regions.Pop();

                //如果开始行和结束行相等 则不处理
                if (startLine == lines.Length - 1)
                {
                    if (startLine == focusLineNumber)
                        return lines[lines.Length - 1]; 
                }
                TextSnapshotLine textSnapshotLine = _sqlEditor.Document.CurrentSnapshot.Lines.FirstOrDefault(o => o.LineNumber == startLine);
                var startOffset = textSnapshotLine.Span.Start;
                TextSnapshotLine iSnapshotLine = _sqlEditor.Document.CurrentSnapshot.Lines.FirstOrDefault(o => o.LineNumber == lines.Length - 1);
                var endOffset = iSnapshotLine.Span.End;

                if (startOffset < endOffset)
                {
                    if (startLine <= focusLineNumber && lines.Length - 1 >= focusLineNumber)
                    {
                        var span = new TextSnapshotSpan(_sqlEditor.Document.CurrentSnapshot, new Span(startOffset, endOffset - startOffset));
                        return span.GetText();
                    }
                }
            }


            return string.Empty;
        }

        private bool SetNextCompletionList(TSqlParserToken? endToken, List<TableReferenceInfo> dic, IList<TSqlParserToken> sqlParserTokens)
        {
            if (endToken != null)
            {
                if (endToken.TokenType == TSqlTokenType.From ||
                    endToken.TokenType == TSqlTokenType.Join ||
                    endToken.TokenType == TSqlTokenType.Into ||
                    endToken.TokenType == TSqlTokenType.Update ||
                    endToken.TokenType == TSqlTokenType.Table)
                {
                    _completionList = _tableCompletionList;
                }
                else if (endToken.TokenType == TSqlTokenType.Select ||
                         endToken.TokenType == TSqlTokenType.Where ||
                         endToken.TokenType == TSqlTokenType.By ||
                         endToken.TokenType == TSqlTokenType.Add ||
                         endToken.TokenType == TSqlTokenType.And ||
                         endToken.TokenType == TSqlTokenType.Column)
                {
                    LoadColumnKeyWorks(dic, string.Empty);
                    _completionList = _columnCompletionList;
                }
                else if (endToken.TokenType == TSqlTokenType.Star ||
                         endToken.TokenType == TSqlTokenType.Semicolon)
                {// * ;
                    _completionList = _defaultCompletionList;
                    return false;
                }
                else if (endToken.TokenType == TSqlTokenType.Exec ||
                         endToken.TokenType == TSqlTokenType.Execute)
                {
                    _completionList = _procCompletionList;
                }
                else if (endToken.TokenType == TSqlTokenType.Dot)
                {// .
                    TSqlParserToken? endSecondToken = null;
                    if (endToken != null)
                    {
                        endSecondToken = GetEndToken(sqlParserTokens, sqlParserTokens.IndexOf(endToken) - 1);
                    }
                    if (endSecondToken != null)
                    {//别名
                     //查找别名是否在表名列表中
                        LoadColumnKeyWorks(dic, endSecondToken.Text);
                        _completionList = _columnCompletionList;
                    }
                }
                else if (endToken.TokenType == TSqlTokenType.TSEqual)
                {
                    _completionList = new List<CompletionInfo>();
                }
                else if (endToken.TokenType == TSqlTokenType.Identifier)
                {
                    //判断上一个关键词是什么
                    TSqlParserToken? lastToken = null;
                    if (endToken != null)
                    {
                        lastToken = GetKeyWordToken(sqlParserTokens, sqlParserTokens.IndexOf(endToken) - 1);
                        //如果是表名 需要切换成默认关键词
                        if (lastToken != null)
                        {
                            if (dic.Count > 0 && dic.Any(o => o.TableName == lastToken.Text || o.Alias == lastToken.Text))
                            {
                                _completionList = _defaultCompletionList;
                                lastToken = null;
                            }
                        }
                        else
                        {
                            if (_completionList.Count(o => o.Text.StartsWith(endToken.Text,StringComparison.CurrentCultureIgnoreCase)) > 0)
                                return true;
                            return false;
                        }
                    } 
                }
                else if (endToken.TokenType == TSqlTokenType.RightParenthesis ||
                        endToken.TokenType == TSqlTokenType.LeftParenthesis ||
                        endToken.TokenType == TSqlTokenType.WhiteSpace ||
                        endToken.TokenType == TSqlTokenType.EqualsSign ||
                        endToken.TokenType == TSqlTokenType.Integer ||
                        endToken.TokenType == TSqlTokenType.SingleLineComment ||
                        endToken.TokenType == TSqlTokenType.Minus ||
                        endToken.TokenType == TSqlTokenType.Plus ||
                        endToken.TokenType == TSqlTokenType.Divide ||
                        endToken.TokenType == TSqlTokenType.AsciiStringLiteral
                        )
                { //() 空格 = - + / ;
                    return false;
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        private void ShowCompletionListWindow(TSqlParserToken? endToken)
        {
            if (_completionList.Count == 0)
            {
                _sqlCompletionListPopup.Close();
                return;
            }
            if (!string.IsNullOrEmpty(filterText))
            {
                //排序 把匹配的放前面
                var tempCompletion = _completionList.Where(o => o.Text.StartsWith(filterText, StringComparison.OrdinalIgnoreCase)).ToList();
                if (tempCompletion.Count > 0)
                {
                    var otherCompletion = _completionList.Except(tempCompletion).ToList(); 
                    List<CompletionInfo> newList = new List<CompletionInfo>();
                    newList.AddRange(tempCompletion);
                    newList.AddRange(otherCompletion);
                    _completionList = newList;
                }
                else 
                {
                    return;
                }
            }

            _sqlCompletionListPopup.Presenter.CompletionListItems.Clear();
            foreach (var item in _completionList)
            {
                _sqlCompletionListPopup.Presenter.CompletionListItems.Add(item);
            }
            if (!_sqlCompletionListPopup.IsVisible)
            {
                int length = 1;
                if(endToken != null && !string.IsNullOrEmpty(endToken.Text))
                {
                    length = endToken.Text.Length;
                }
                CaretPosition caretPositionStart = new CaretPosition(_sqlEditor.Document, 
                    _sqlEditor.CaretPosition.LineNumber, 
                    _sqlEditor.CaretPosition.ColumnNumber - length);
                CaretPosition caretPositionEnd = new CaretPosition(_sqlEditor.Document,
                   _sqlEditor.CaretPosition.LineNumber,
                   _sqlEditor.CaretPosition.ColumnNumber);
                _sqlCompletionListPopup.Show(caretPositionStart, caretPositionEnd); 
            }
            else
            {
                if (_lastKeyWord == " ")
                {
                    //_sqlCompletionListPopup.StartPosition.MoveToPosition(new CaretPosition(_sqlEditor.Document, _sqlEditor.CaretPosition.LineNumber, _sqlEditor.CaretPosition.ColumnNumber));
                    //_sqlCompletionListPopup.EndPosition.MoveToPosition(new CaretPosition(_sqlEditor.Document, _sqlEditor.CaretPosition.LineNumber, _sqlEditor.CaretPosition.ColumnNumber));
                }
                else
                {
                    if (string.IsNullOrEmpty(filterText))
                    {
                        _sqlCompletionListPopup.Close();
                    }
                }
            }
        }
 
        private TSqlParserToken? GetEndToken(IList<TSqlParserToken> sqlParserTokens,int index)
        {
            if (index < 0)
                return null;

            if (sqlParserTokens[index].TokenType == TSqlTokenType.End ||
                sqlParserTokens[index].TokenType == TSqlTokenType.EndOfFile)
            {
                return GetEndToken(sqlParserTokens, index - 1);
            }

            return sqlParserTokens[index];
        }

        private TSqlParserToken? GetKeyWordToken(IList<TSqlParserToken> sqlParserTokens, int index)
        {
            if (index < 0)
                return null;

            if (sqlParserTokens[index].TokenType == TSqlTokenType.End ||
                sqlParserTokens[index].TokenType == TSqlTokenType.EndOfFile ||
                sqlParserTokens[index].TokenType == TSqlTokenType.WhiteSpace ||
                sqlParserTokens[index].TokenType == TSqlTokenType.Identifier)
            {
                return GetEndToken(sqlParserTokens, index - 1);
            }

            return sqlParserTokens[index];
        }

        public void SelectAll()
        {
            _sqlEditor.SelectAll();
        }

        public void ClearText()
        {
            SelectedText = string.Empty;
            _sqlEditor.SelectAll();
            _sqlEditor.Insert("");
        }

        public void IncreaseText()
        {
            Selection selection = _sqlEditor.Selection;
            if(selection.IsEmpty)
            {

            }
            else
            {
                var start = selection.StartPosition;
                var end = selection.EndPosition;
                // 确保起始行号小于结束行号
                if (start.LineNumber > end.LineNumber)
                {
                    (start, end) = (end, start);
                }

                // 遍历选中的每一行
                for (int lineNumber = start.LineNumber; lineNumber <= end.LineNumber; lineNumber++)
                { 
                    // 在当前行开头插入注释符号
                    TextSnapshotLine? textSnapshotLine = _sqlEditor.Document.CurrentSnapshot.Lines.FirstOrDefault(o => o.LineNumber == lineNumber);
                    if(textSnapshotLine != null)
                        textSnapshotLine.Snapshot.TextDocument.Insert(textSnapshotLine.Span.Start, "//");
                }

            }
        }

        public void DecreaseText()
        {
            Selection selection = _sqlEditor.Selection;
            if (selection.IsEmpty)
            {

            }
            else
            {
                var start = selection.StartPosition;
                var end = selection.EndPosition;
                // 确保起始行号小于结束行号
                if (start.LineNumber > end.LineNumber)
                {
                    (start, end) = (end, start);
                }

                // 遍历选中的每一行
                for (int lineNumber = start.LineNumber; lineNumber <= end.LineNumber; lineNumber++)
                {
                    // 在当前行开头插入注释符号
                    TextSnapshotLine? textSnapshotLine = _sqlEditor.Document.CurrentSnapshot.Lines.FirstOrDefault(o => o.LineNumber == lineNumber);
                    if (textSnapshotLine != null)
                    {
                        string text = textSnapshotLine.GetText();
                        if (text.StartsWith("//"))
                        {
                            Span span = new Span(textSnapshotLine.Span.Start, 2);
                            textSnapshotLine.Snapshot.TextDocument.Delete(span);
                        }
                    }
                }

            }
        }

        public void Cut()
        {
            _sqlEditor.Cut();
        }

        public void Paste()
        {
            _sqlEditor.Paste();
        }

        public void FindOrReplace()
        {
            _sqlEditor.Commands.OpenFindDialogCommand.Execute(null);
        }

        public void Undo()
        {
            _sqlEditor.Undo();
        }

        public void Redo()
        {
            _sqlEditor.Redo();
        }

        public void Save()
        {
            if (IsNewDocument)
            {
                //弹出保存文件对话框
                //默认打开当前目录下的 Document文件夹
                string directoryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Document");
                if (!Directory.Exists(directoryPath))
                    Directory.CreateDirectory(directoryPath);
                RadSaveFileDialog dialog = new RadSaveFileDialog()
                {
                    InitialDirectory = directoryPath,
                    Filter = "文本文件 (*.txt)|*.txt|SQL 文件 (*.sql)|*.sql",
                    FilterIndex = 5,
                };
                if (dialog.ShowDialog() == true)
                {
                    FilePath = dialog.FileName;
                    IsNewDocument = false; 
                }
                else
                {
                    return;
                }
            }
            _originalText = _sqlEditor.Document.CurrentSnapshot.GetText();
            ChangeTitle();

            using StreamWriter writer = new StreamWriter(FilePath, false, Encoding.UTF8);
            writer.Write(_sqlEditor.Document.CurrentSnapshot.GetText());
        }

        private void ChangeTitle()
        {
            string titleName = IsNewDocument ? "新文档" : Path.GetFileName(FilePath);
            IsChangeDocument = _sqlEditor.Document.CurrentSnapshot.GetText() != _originalText;
            
            DocumentHeaderTitle = titleName;
        }
    }
}
